-- PRAGMA standard control signal mapping:
-- clk								=> clk
-- reset								=> reset
-- PAY ATTENTION:					RESET IS ACTIVE LOW
-- control_in	(0) 				=> distortion_enable
--					(7 downto 4) 	=> clipping_control
--					(3 downto 1) 	=> UNUSED
--
--	control_out	(3 downto 0)	<= clipping_control
-- 
-- PCM_data_in_right				=> PCM_data_in_right
-- PCM_data_in_left				=> PCM_data_in_left
-- PCM_data_out_right			<= PCM_data_out_right
-- PCM_data_out_left				<= PCM_data_out_left

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;

entity PRM_time_1 is
port (
	clk 						: in std_logic;
	clk_48k					: in std_logic;
	reset 					: in std_logic;
	
	control_in 				: in std_logic_vector(7 downto 0);
	control_out				: out std_logic_vector(3 downto 0);
	
	PCM_data_in_right 	: in std_logic_vector(15 downto 0);
	PCM_data_in_left 		: in std_logic_vector(15 downto 0);
	PCM_data_out_right 	: out std_logic_vector(15 downto 0);
	PCM_data_out_left 	: out std_logic_vector(15 downto 0)
	);
end entity PRM_time_1;
	
architecture behaviour of PRM_time_1 is
	signal clipping_value		: std_logic_vector(15 downto 0);
	signal clipping_control		: std_logic_vector(3 downto 0);
	signal distortion_enable	: std_logic;
	signal data_ready_left		: std_logic;
	signal data_ready_right		: std_logic;

begin
	-- mapping internal signals to PRAGMA standard
	clipping_control 	<= control_in(7 downto 4);
	distortion_enable	<= control_in(0);
	
	control_out 		<= clipping_control;
	--control_out(0)		<= data_ready_left;
	--control_out(1)		<= data_ready_right;
	--control_out(2)		<= distortion_enable;
	
	clipping_value <= shl("0000000000000001", clipping_control);
	
	p_left: process(clk_48k, reset)
	begin
	if (reset = '0') then
		data_ready_left 	<= '0';
		PCM_data_out_left <= (others => '0');
	elsif (clk_48k'event and clk_48k = '1') then
		if (distortion_enable = '1') then	
			if (PCM_data_in_left(15) = '1') then		--negative
				if ((PCM_data_in_left) < (-clipping_value)) then
					PCM_data_out_left <= '1' & (not clipping_value(14 downto 0));
				else
					PCM_data_out_left <= PCM_data_in_left;
				end if;
			else													--positive
				if (PCM_data_in_left > ('0' & clipping_value(14 downto 0))) then
					PCM_data_out_left <= '0' & clipping_value(14 downto 0);
				else
					PCM_data_out_left <= PCM_data_in_left;
				end if;
			end if;
		else
			PCM_data_out_left <= PCM_data_in_left;
		end if;
		data_ready_left <= '1';
	end if;
	end process;
	
	p_right: process(clk_48k, reset)
	begin
	if (reset = '0') then
		data_ready_right 		<= '0';
		PCM_data_out_right 	<= (others => '0');
	elsif (clk_48k'event and clk_48k = '1') then
		if (distortion_enable = '1') then	
			if (PCM_data_in_right(15) = '1') then		--negative
				if ((PCM_data_in_right) < (-clipping_value)) then
					PCM_data_out_right <= '1' & (not clipping_value(14 downto 0));
				else
					PCM_data_out_right <= PCM_data_in_right;
				end if;
			else													--positive
				if (PCM_data_in_right > ('0' & clipping_value(14 downto 0))) then
					PCM_data_out_right <= '0' & clipping_value(14 downto 0);
				else
					PCM_data_out_right <= PCM_data_in_right;
				end if;
			end if;
		else
			PCM_data_out_right <= PCM_data_in_right;
		end if;
		data_ready_right <= '1';
	end if;
	end process;

end architecture behaviour;
